package ltd.ueic.allypay.alipay.controller;

import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.response.*;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import ltd.ueic.allypay.alipay.config.AlipayConfig;
import ltd.ueic.allypay.alipay.service.AliPayService;
import ltd.ueic.extra.support.web.ResponseBuilder;
import ltd.ueic.extra.support.web.ResponseEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * @author Kevin Yang
 * @version 1.0.0
 * Created by Kevin Yang on 2018/11/30 15:50.
 */
@Slf4j
@Controller
@RequestMapping(value = "/alipay")
public class AliPayController {

    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private AlipayConfig alipayConfig;

    @ApiOperation(value = "统一收单下单并支付页面接口", notes = "手机网站支付")
    @RequestMapping(value = "/trade/wap/pay", method = RequestMethod.POST)
    public void wappay(AlipayTradeWapPayModel bizModel, String returnUrl, String notifyUrl, HttpServletResponse response) {
        AlipayTradeWapPayResponse payResponse = aliPayService.wapPay(bizModel, returnUrl, notifyUrl);
        try {
            String form = "";
            if (null != payResponse) {
                // 调用SDK生成表单
                form = payResponse.getBody();
            }
            response.setContentType("text/html;charset=" + alipayConfig.getCharset());
            //直接将完整的表单html输出到页面
            response.getWriter().write(form);
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            log.error("AliPayController--> wappay | 调用wappay支付SDK出现异常", e);
        }
    }

    @ApiOperation(value = "统一收单下单并支付页面接口", notes = "电脑网站支付")
    @RequestMapping(value = "/trade/page/pay", method = RequestMethod.POST)
    public void pagepay(AlipayTradePagePayModel bizModel, String returnUrl, String notifyUrl, HttpServletResponse response) {
        AlipayTradePagePayResponse payResponse = aliPayService.pagePay(bizModel, returnUrl, notifyUrl);
        try {
            // 调用SDK生成表单
            String form = payResponse.getBody();
            response.setContentType("text/html;charset=" + alipayConfig.getCharset());
            //直接将完整的表单html输出到页面
            response.getWriter().write(form);
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            log.error("AliPayController--> pagepay | 调用pagepay支付SDK出现异常", e);
        }
    }

    @ApiOperation(value = "支付回调参数验证接口", notes = "支付回调和通知地址回调参数验证")
    @RequestMapping(value = "/trade/verify/pay/return", method = RequestMethod.POST)
    public ResponseEntity verify_pay_return(Map requestParams) {
        try {
            //获取支付宝POST过来反馈信息
            Map<String, String> params = aliPayService.getPayReturnParams(requestParams);
            Boolean verify_result = aliPayService.verifyReturn(params);
            //验证成功
            if (verify_result) {
                return ResponseBuilder.ok("验证成功", params);
            }
        } catch (UnsupportedEncodingException e) {
            log.error("AliPayController --> verify_pay_return | 验证支付返回参数异常", e);
        }
        return ResponseBuilder.build(PayResponseStatus.PAY_RETURN_PARAM_VERIFY_FAIL, "验证支付返回参数异常");
    }

    @ApiOperation(value = "统一收单交易关闭接口", notes = "用于交易创建后，用户在一定时间内未进行支付，可调用该接口直接将未付款的交易进行关闭")
    @RequestMapping(value = "/trade/close", method = RequestMethod.POST)
    public ResponseEntity trade_close(String outTradeNo, String tradeNo, String operatorId) {
        try {
            AlipayTradeCloseResponse closeResponse = aliPayService.close(outTradeNo, tradeNo, operatorId);
            return ResponseBuilder.ok(closeResponse);
        } catch (Exception e) {
            log.error("AliPayController --> trade_close | 统一收单交易关闭接口异常", e);
            return ResponseBuilder.build(PayResponseStatus.TRADE_CLOSE_ERROR, "AliPayController --> trade_close | 统一收单交易关闭接口异常");
        }
    }

    @ApiOperation(value = "统一收单线下交易查询", notes = "该接口提供所有支付宝支付订单的查询，商户可以通过该接口主动查询订单状态，完成下一步的业务逻辑。 需要调用查询接口的情况： 当商户后台、网络、服务器等出现异常，商户系统最终未接收到支付通知； 调用支付接口后，返回系统错误或未知交易状态情况； 调用alipay.trade.pay，返回INPROCESS的状态； 调用alipay.trade.cancel之前，需确认支付状态；")
    @RequestMapping(value = "/trade/query", method = RequestMethod.POST)
    public ResponseEntity trade_query(String outTradeNo, String tradeNo, String orgPid) {
        try {
            AlipayTradeQueryResponse queryResponse = aliPayService.query(outTradeNo, tradeNo, orgPid);
            return ResponseBuilder.ok(queryResponse);
        } catch (Exception e) {
            log.error("AliPayController --> trade_query | 统一收单线下交易查询接口异常", e);
            return ResponseBuilder.build(PayResponseStatus.TRADE_QUERY_ERROR, "AliPayController --> trade_query | 统一收单线下交易查询接口异常");
        }
    }

    @ApiOperation(value = "统一收单交易退款接口", notes = "当交易发生之后一段时间内，由于买家或者卖家的原因需要退款时，卖家可以通过退款接口将支付款退还给买家，支付宝将在收到退款请求并且验证成功之后，按照退款规则将支付款按原路退到买家帐号上。 交易超过约定时间（签约时设置的可退款时间）的订单无法进行退款 支付宝退款支持单笔交易分多次退款，多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交，要采用原来的退款单号。总退款金额不能超过用户实际支付金额")
    @RequestMapping(value = "/trade/refund", method = RequestMethod.POST)
    public ResponseEntity trade_refund(String outTradeNo, String tradeNo, String refundAmount, String refundReason, String outRequestNo) {
        try {
            AlipayTradeRefundResponse refundResponse = aliPayService.refund(outTradeNo, tradeNo, refundAmount, refundReason, outRequestNo);
            return ResponseBuilder.ok(refundResponse);
        } catch (Exception e) {
            log.error("AliPayController --> trade_refund | 统一收单交易退款接口异常", e);
            return ResponseBuilder.build(PayResponseStatus.TRADE_REFUND_ERROR, "AliPayController --> trade_refund | 统一收单交易退款接口异常");
        }
    }

    @ApiOperation(value = "统一收单交易退款查询", notes = "商户可使用该接口查询自已通过alipay.trade.refund提交的退款请求是否执行成功。 该接口的返回码10000，仅代表本次查询操作成功，不代表退款成功。如果该接口返回了查询数据，则代表退款成功，如果没有查询到则代表未退款成功，可以调用退款接口进行重试。重试时请务必保证退款请求号一致。")
    @RequestMapping(value = "/trade/fastpay/refund/query", method = RequestMethod.POST)
    public ResponseEntity trade_query_refund(String outTradeNo, String tradeNo, String outRequestNo) {
        try {
            AlipayTradeFastpayRefundQueryResponse refundQueryResponse = aliPayService.refundQuery(outTradeNo, tradeNo, outRequestNo);
            return ResponseBuilder.ok(refundQueryResponse);
        } catch (Exception e) {
            log.error("AliPayController --> trade_query_refund | 统一收单交易退款查询接口异常", e);
            return ResponseBuilder.build(PayResponseStatus.TRADE_REFUND_QUERY_ERROR, "AliPayController --> trade_query_refund | 统一收单交易退款查询接口异常");
        }
    }

    @ApiOperation(value = "查询对账单下载地址", notes = "为方便商户快速查账，支持商户通过本接口获取商户离线账单下载地址")
    @RequestMapping(value = "/data/dataservice/bill/downloadurl/query", method = RequestMethod.POST)
    public ResponseEntity query_bill_downloadurl(String billType, String billDate) {
        try {
            AlipayDataDataserviceBillDownloadurlQueryResponse downloadurlQueryResponse = aliPayService.downloadUrl(billType, billDate);
            return ResponseBuilder.ok(downloadurlQueryResponse);
        } catch (Exception e) {
            log.error("AliPayController --> query_bill_downloadurl | 查询对账单下载地址接口异常", e);
            return ResponseBuilder.build(PayResponseStatus.BILL_DOWNLOADURL_QUERY_ERROR, "AliPayController --> query_bill_downloadurl | 查询对账单下载地址接口异常");
        }
    }

}
